//  A*

/////     /////
init_arr %areafind (1) 34, 36 655, 340 32 32    //      Findcolor

set $start A   //   A  
set $ending B  //   B  

set #start_color 950016   //   
set #white 16777215  //   
set #wall 0 //  
set #collect1 16721408 // , 
set #collect2 55551 // 



gosub create_map
//save_array %map C:\Users\abc\Desktop\map.txt          // 
//save_array %coord C:\Users\abc\Desktop\coord.txt      //   
//save_array %coord2 C:\Users\abc\Desktop\coord2.txt    //     ,    
//save_array %coord3 C:\Users\abc\Desktop\coord3.txt    //    %map
//end_script

// 0 -      , 1 -   
set #angle 0

set #click 1       //  ,    . 1 - , 0 -
set #showpoint 0  //    (  )


//    
//  
init_arr %vector (1) -1 -1 0 1 1 1 0 -1     // x
init_arr %vector (2) 0 1 1 1 0 -1 -1 -1     // y

set #handle workwindow
if  workwindow = 0
    Log   
    Log  
    stop_script
end_if
if  size(%map) = 0
    Log     .
    Log  
    stop_script
end_if
if  size(%coord) = 0
    Log     .
    Log  
    stop_script
end_if

log clear
log mode compact


set #width size(%map[])
set #height size(%map)
set %sizemap indexof (%map (0))
set #sizemap size(%sizemap) + 1


set #size_coord2 size(%coord2)


gosub dist   //    
//save_array %ending C:\Users\abc\Desktop\ending.txt  //    

init_arr %start (1) %ending [1 1] %ending [1 2]
set #x %ending [2 1]
set #y %ending [2 2]
set %map [#x #y] $ending

set #j 1
while #j <= size(%ending)   //       
    set size(%tmp)
    set size(%open)
    set size(%close)
    set size(%curr)
    set size(%resultarray)

    gosub Astar
    init_arr %start (1) %ending [#j 1] %ending [#j 2]
    set #tmp #j + 1
    set #x %ending [#tmp 1]
    set #y %ending [#tmp 2]
    set %map [#x #y] $ending
    set #j #j + 1
end_while
end_script



:dist
    set #persX %coord2 [size(%coord2) 1]
    set #persY %coord2 [size(%coord2) 2]
    set #size_coord2 size(%coord3)
    init_arr %ending (1) %coord3[#size_coord2 1] %coord3[#size_coord2 2]
    delete_array %coord2 -#size_coord2
    delete_array %coord3 -#size_coord2

    for #ii 2 eval(size(%coord2)+1)
        set #min 9999999
        set #minNum -1

        for #i 1 size(%coord2)
            set #x %coord2[#i 1]
            set #y %coord2[#i 2]
            set #dist round(point_distance(#persX #persY #x #y ))
            if  #dist < #min
                set #min #dist
                set #minNum #i
            end_if
        end_for
        if  #minNum > 0
            //        log %coord2 [#minNum 1]    %coord2 [#minNum 2]
            init_arr %ending (#ii) %coord3[#minNum 1] %coord3[#minNum 2]
            set #persX %coord2 [#minNum 1]
            set #persY %coord2 [#minNum 2]
            delete_array  %coord2 -#minNum
            delete_array  %coord3 -#minNum
        end_if
    end_for
return


:create_map
    set #startX %areafind [1 1]
    set #startY %areafind [1 2]
    set #endX %areafind [1 3]
    set #endY %areafind [1 4]
    set #stepX %areafind [1 5]
    set #stepY %areafind [1 6]

    set #z1 0
    set #z 0
    set #a findcolor (#startX #startY #endX #endY #stepX #stepY (0-16777215) %find)
    //    hint #a
    if  #a > 0
        set #z 0
        for #i 1 eval((((#endY - #startY) / #stepY) + 1))
            for #j 1 eval(((#endX - #startX) / #stepX) + 1)
                set #z #z + 1
                switch %find [#z 3]
                    case #white:    // ,    
                        set %map [#i #j] 0
                        set %coord [#i #j] %find [#z 1] %find [#z 2]
                        break
                    case #wall:   // 
                        set %map [#i #j] 1
                        set %coord [#i #j] %find [#z 1] %find [#z 2]
                        break
                    case #collect1:     //  1
                        set %map [#i #j] 1
                        set %coord [#i #j] %find [#z 1] %find [#z 2]
                        set #z1 #z1 + 1
                        init_arr %coord2 (#z1) %find [#z 1] %find [#z 2]  //  
                        init_arr %coord3 (#z1) #i #j               //    %map
                        break
                    case #collect2:     //  2
                        set %map [#i #j] 1
                        set %coord [#i #j] %find [#z 1] %find [#z 2]
                        set #z1 #z1 + 1
                        init_arr %coord2 (#z1) %find [#z 1] %find [#z 2]
                        init_arr %coord3 (#z1) #i #j               //    %map
                        break
                    case :
                        set %map [#i #j] 1
                        set %coord [#i #j] %find [#z 1] %find [#z 2]
                end_switch
            end_for
        end_for

        set #z 0
        for #i 1 eval((((#endY - #startY) / #stepY) + 1))
            for #j 1 eval(((#endX - #startX) / #stepX) + 1)
                set #z #z + 1
                if  %find [#z 3] = #start_color       //  
                    set %map [#i #j] $start
                    set %coord [#i #j] %find [#z 1] %find [#z 2]
                    set #z1 #z1 + 1
                    init_arr %coord2 (#z1) %find [#z 1] %find [#z 2]
                    init_arr %coord3 (#z1) #i #j            //       %map
                end_if
            end_for
        end_for
    end_if
return


:Astar
    // F,  G,  H,  _,   (X Y),   (X:Y),    (X Y)
    init_arr %open (1) 0 0 0 0 %start [1 1] %start [1 2] %start [1 1]:%start [1 2] %start [1 1] %start [1 2]
    while 1 = 1
        sort_array %open                    //    F
        set #sizeclose size(%close) + 1
        init_arr %curr (1) %open [1 1] %open [1 2] %open [1 3] %open [1 4] %open [1 5] %open [1 6] %open [1 7] %open [1 8] %open [1 9]  //  
        init_arr %close (#sizeclose) %open [1 1] %open [1 2] %open [1 3] %open [1 4] %open [1 5] %open [1 6] %open [1 7] %open [1 8] %open [1 9]  //    
        if  #showpoint = 1
            left %coord[%curr[1 5] %curr[1 6]]
            wait 1
        end_if
        delete_array %open -1     //    

        //    8   
        for #i 1 8
            if  #angle = 1 or mod(#i 2) = 1        //           
                set #x %curr [1 5] + %vector [1 #i]
                set #y %curr [1 6] + %vector [2 #i]
                init_arr %tmp (1) #x : #y
                //     
                set %resultclose indexof (%close (%tmp[1]))
                if  #x > 0 and #y > 0 and #x <= #height and #y <= #width     //       
                    if  (%map [#x #y] = 0 or %map [#x #y] = $ending) and size(%resultclose) = 0   // (        )      
                        set %resultopen indexof (%open (%tmp[1]))  //       ,    .
                        if  size( %resultopen) = 0
                            set #sizeopen size(%open) + 1
                            if  mod(#i 2) = 1
                                set #g %curr [1 2] + 10                //  G
                            else
                                set #g %curr [1 2] + 14
                            end_if
                            set #h (abs(eval(#x - %ending [#j 1])) + abs(eval(#y - %ending [#j 2]))) * 10      //  H
                            set #f #g + #h                                                                   //  F
                            init_arr %open (#sizeopen) #f #g #h #i #x #y %tmp[1] %curr [1 5] %curr [1 6]
                        else
                            //      
                            set #tmp %resultopen [1 1]  //     
                            set #g1 %open[#tmp 2]       //  G     
                            if  mod(#i 2) = 1
                                set #g %curr [1 2] + 10     //  G   +        
                            else
                                set #g %curr [1 2] + 14
                            end_if
                            if  #g < #g1                //    
                                //        
                                //     
                                set #h (abs(eval(#x - %ending [#j 1])) + abs(eval(#y - %ending [#j 2]))) * 10
                                set #f #g + #h
                                init_arr %open (#tmp) #f #g #h #i #x #y %tmp[1] %curr [1 5] %curr [1 6]
                            end_if
                        end_if
                    end_if
                end_if
            end_if
        end_for
        //        log   %curr [1 5] = %ending [#j 1] and %curr [1 6] = %ending [#j 2]
        //           
        if  (%curr [1 5] = %ending [#j 1] and %curr [1 6] = %ending [#j 2]) or size(%open) = 0
            if  %curr [1 5] != %ending [#j 1] and %curr [1 6] != %ending [#j 2]
                log   
                end_script
            end_if

            //      B   A     
            set size(%tmp)

            init_arr %tmp (1)  %ending [#j 1] %ending [#j 2]
            set #zz size(%tmp) + 1
            init_arr %tmp (#zz) %close [size(%close) 8] %close [size(%close) 9] %close [size(%close) 4]
            while %tmp [size(%tmp) 1] != %start [1 1] or %tmp [size(%tmp) 2] != %start [1 2]
                set %pathAB indexof (%close (%tmp [size(%tmp) 1]:%tmp [size(%tmp) 2]))
                set #zz size(%tmp) + 1
                init_arr %tmp (#zz) %close [%pathAB [1 1] 8] %close [%pathAB [1 1] 9] %close [%pathAB [1 1] 4]
            end_while

            set #z 0
            set delimiter ' '
            for #i size(%tmp) 1 -1
                set #z #z + 1
                init_arr %resultarray (#z) %tmp [#i]
            end_for
            set delimiter
            // save_array %open C:\Users\abc\Desktop\open.txt      //  
            // save_array %close C:\Users\abc\Desktop\close.txt    //  
            // save_array %resultarray C:\Users\abc\Desktop\resultarray.txt   //         %map


            //  
            if  #click = 1
                gosub hod
            end_if
            break
        end_if
        //        if  #hint = 1
        //            hint  size(%close)  #sizemap .
        //        end_if
    end_while
return

:hod
    showwindow #handle
    wait 500
    for #i 2 size(%resultarray)
        kleft %coord[%resultarray [#i 1] %resultarray [#i 2]]
        // log  %coord[%resultarray [#i 1] %resultarray [#i 2]]
        wait 2
    end_for
return
